/*
 * Copyright (c) 2009 John Pritchard, WTKX Project Group
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package wtkx;


import wtkx.ui.Mouse;
import wtkx.ui.Platform;

/**
 * A layer of code for its subclasses: input delegation to children.
 * 
 * <h4>Note on Container</h4>
 * 
 * In other widget collections, the Container has special role and
 * signficance as a peer or sibling of Component.  This not the case
 * in this package.
 * 
 * For example, the {@link Button} class employs the containment of
 * one or more {@link Image} icons or text {@link Label Labels}
 * visually, but extents {@link Component} to not have its input
 * delegated.
 * 
 * In this package, classes that are subclasses of "container" have no
 * special significance beyond {@link Component}.  Generally for the
 * evolution of this package, it's possible that a class in this
 * package may change from or to subclassing this class -- so for this
 * reason (at least), writing code detecting this class rather than
 * the state of {@link Component} is strongly discouraged.
 * 
 * <h3>Input delegation</h3>
 * 
 * The mouse input code here influences the keyboard input, which
 * requires no further code for correct delegation. 
 * 
 *
 * @author gbrown
 * @author jdp
 */
public abstract class Container
    extends Component
{

    public Container(){
        super();
        this.validateTopDown = true;
        this.focusableComponent = false;

        this.border.hidden();//(no bg fill by default)
    }


    public void layout(){
        super.layout();
    }
    public boolean mouseMove(float x, float y) {
        boolean consumed = false;

        if (this.enabled) {

            if (mouseOverComponent != null && !mouseOverComponent.isMouseOver()) {
                mouseOverComponent = null;
            }

            Component component = this.getComponentAt(x, y);

            if (mouseOverComponent != component) {

                if (mouseOverComponent != null) {
                    mouseOverComponent.mouseOut();
                }

                mouseOverComponent = component;

                if (mouseOverComponent == null) {

                    Mouse.setCursor(this);
                }
                else {
                    mouseOverComponent.mouseOver();

                    Mouse.setCursor(mouseOverComponent);
                }
            }

            if (component != null) {

                consumed = component.mouseMove((x - component.x), (y - component.y));
            }

            if (!consumed) {
                consumed = super.mouseMove(x, y);
            }
        }

        return consumed;
    }
    @Override
    public void mouseOut() {

        if (mouseOverComponent != null && mouseOverComponent.isMouseOver()) {

            mouseOverComponent.mouseOut();
        }

        mouseOverComponent = null;

        super.mouseOut();
    }
    @Override
    public boolean mouseDown(Mouse.Button button, float x, float y) {
        boolean consumed = false;

        if (this.enabled) {

            Component component = this.getComponentAt(x, y);

            long currentTime = System.currentTimeMillis();
            int multiClickInterval = Platform.getMultiClickInterval();
            if (mouseDownComponent == component
                && currentTime - mouseDownTime < multiClickInterval)
            {
                mouseClickCount++;
            }
            else {
                mouseDownTime = System.currentTimeMillis();
                mouseClickCount = 1;
            }

            mouseDownComponent = component;

            if (component != null) {
                consumed = component.mouseDown(button, (x - component.x), (y - component.y));
            }

            if (!consumed) {
                consumed = super.mouseDown(button, x, y);
            }
        }
        return consumed;
    }
    @Override
    public boolean mouseUp(Mouse.Button button, float x, float y) {
        boolean consumed = false;

        if (this.enabled) {

            Component component = this.getComponentAt(x, y);

            if (component != null) {
                consumed = component.mouseUp(button, (x - component.x), (y - component.y));
            }

            if (!consumed) {
                consumed = super.mouseUp(button, x, y);
            }

            if (component != null
                && component == mouseDownComponent
                && mouseDownComponent.isEnabled()
                && mouseDownComponent.isVisible())
            {
                mouseClickConsumed = component.mouseClick(button, (x - component.x),
                                                          (y - component.y), mouseClickCount);
            }
        }

        return consumed;
    }
    @Override
    public boolean mouseClick(Mouse.Button button, float x, float y, int count) {
        if (this.enabled) {
            if (!mouseClickConsumed) {

                mouseClickConsumed = super.mouseClick(button, x, y, count);
            }
        }
        return mouseClickConsumed;
    }
    @Override
    public boolean mouseWheel(Mouse.ScrollType scrollType, int scrollAmount,
                              int wheelRotation, float x, float y)
    {
        boolean consumed = false;

        if (this.enabled) {

            Component component = this.getComponentAt(x, y);

            if (component != null) {
                consumed = component.mouseWheel(scrollType, scrollAmount, wheelRotation,
                                                (x - component.x), (y - component.y));
            }

            if (!consumed) {
                consumed = super.mouseWheel(scrollType, scrollAmount, wheelRotation, x, y);
            }
        }
        return consumed;
    }
}
